

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>mindspore.scipy.sparse.linalg &mdash; MindSpore master documentation</title>
  

  
  <link rel="stylesheet" href="../../../../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../../../../_static/pygments.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../../" src="../../../../_static/documentation_options.js"></script>
        <script src="../../../../_static/jquery.js"></script>
        <script src="../../../../_static/underscore.js"></script>
        <script src="../../../../_static/doctools.js"></script>
        <script src="../../../../_static/language_data.js"></script>
        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    
    <script type="text/javascript" src="../../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../../genindex.html" />
    <link rel="search" title="Search" href="../../../../search.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../../../../index.html" class="icon icon-home"> MindSpore
          

          
          </a>

          
            
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p class="caption"><span class="caption-text">MindSpore Python API</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.html">mindspore</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.common.initializer.html">mindspore.common.initializer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.communication.html">mindspore.communication</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.compression.html">mindspore.compression</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.context.html">mindspore.context</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.html">mindspore.dataset</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.audio.html">mindspore.dataset.audio</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.config.html">mindspore.dataset.config</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.text.html">mindspore.dataset.text</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.transforms.html">mindspore.dataset.transforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.dataset.vision.html">mindspore.dataset.vision</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.mindrecord.html">mindspore.mindrecord</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.nn.html">mindspore.nn</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.nn.probability.html">mindspore.nn.probability</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.nn.transformer.html">mindspore.nn.transformer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.numpy.html">mindspore.numpy</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.ops.html">mindspore.ops</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.parallel.html">mindspore.parallel</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.parallel.nn.html">mindspore.parallel.nn</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.profiler.html">mindspore.profiler</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.scipy.html">mindspore.scipy</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.train.html">mindspore.train</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../../api_python/mindspore.boost.html">mindspore.boost</a></li>
</ul>
<p class="caption"><span class="caption-text">MindSpore C++ API</span></p>
<ul>
<li class="toctree-l1"><a class="reference external" href="https://www.mindspore.cn/lite/api/zh-CN/master/api_cpp/mindspore.html">MindSpore Lite↗</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../../index.html">MindSpore</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../../../index.html" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../../../index.html">Module code</a> &raquo;</li>
        
      <li>mindspore.scipy.sparse.linalg</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <h1>Source code for mindspore.scipy.sparse.linalg</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright 2021 Huawei Technologies Co., Ltd</span>
<span class="c1">#</span>
<span class="c1"># Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span class="c1"># you may not use this file except in compliance with the License.</span>
<span class="c1"># You may obtain a copy of the License at</span>
<span class="c1">#</span>
<span class="c1"># http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="c1">#</span>
<span class="c1"># Unless required by applicable law or agreed to in writing, software</span>
<span class="c1"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span class="c1"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="c1"># See the License for the specific language governing permissions and</span>
<span class="c1"># limitations under the License.</span>
<span class="c1"># ============================================================================</span>
<span class="sd">&quot;&quot;&quot;Sparse linear algebra submodule&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">...</span> <span class="kn">import</span> <span class="n">nn</span><span class="p">,</span> <span class="n">ms_function</span>
<span class="kn">from</span> <span class="nn">...</span> <span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">mnp</span>
<span class="kn">from</span> <span class="nn">...ops</span> <span class="kn">import</span> <span class="n">functional</span> <span class="k">as</span> <span class="n">F</span>
<span class="kn">from</span> <span class="nn">..linalg</span> <span class="kn">import</span> <span class="n">solve_triangular</span>
<span class="kn">from</span> <span class="nn">..linalg</span> <span class="kn">import</span> <span class="n">cho_factor</span><span class="p">,</span> <span class="n">cho_solve</span>
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">_INT_ZERO</span><span class="p">,</span> <span class="n">_INT_NEG_ONE</span><span class="p">,</span> <span class="n">_normalize_matvec</span><span class="p">,</span> <span class="n">_to_tensor</span><span class="p">,</span> <span class="n">_safe_normalize</span><span class="p">,</span> <span class="n">_eps</span><span class="p">,</span> <span class="n">float_types</span>
<span class="kn">from</span> <span class="nn">..utils_const</span> <span class="kn">import</span> <span class="n">_raise_value_error</span><span class="p">,</span> <span class="n">_raise_type_error</span>


<span class="k">def</span> <span class="nf">gram_schmidt</span><span class="p">(</span><span class="n">Q</span><span class="p">,</span> <span class="n">q</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    do Gram–Schmidt process to normalize vector v</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">h</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">Q</span><span class="o">.</span><span class="n">T</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span>
    <span class="n">Qh</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">Q</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
    <span class="n">q</span> <span class="o">=</span> <span class="n">q</span> <span class="o">-</span> <span class="n">Qh</span>
    <span class="k">return</span> <span class="n">q</span><span class="p">,</span> <span class="n">h</span>


<span class="k">def</span> <span class="nf">arnoldi_iteration</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">H</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Performs a single (the k&#39;th) step of the Arnoldi process.&quot;&quot;&quot;</span>
    <span class="n">v_</span> <span class="o">=</span> <span class="n">V</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">k</span><span class="p">]</span>
    <span class="n">v</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">A</span><span class="p">(</span><span class="n">v_</span><span class="p">))</span>
    <span class="n">v</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="n">gram_schmidt</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
    <span class="n">_</span><span class="p">,</span> <span class="n">v_norm_0</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
    <span class="n">tol</span> <span class="o">=</span> <span class="n">_eps</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">*</span> <span class="n">v_norm_0</span>
    <span class="n">unit_v</span><span class="p">,</span> <span class="n">v_norm_1</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">tol</span><span class="p">)</span>
    <span class="n">V</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">unit_v</span>
    <span class="n">h</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">v_norm_1</span>
    <span class="n">H</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">h</span>
    <span class="n">breakdown</span> <span class="o">=</span> <span class="n">v_norm_1</span> <span class="o">==</span> <span class="mi">0</span>
    <span class="k">return</span> <span class="n">V</span><span class="p">,</span> <span class="n">H</span><span class="p">,</span> <span class="n">breakdown</span>


<span class="nd">@ms_function</span>
<span class="k">def</span> <span class="nf">rotate_vectors</span><span class="p">(</span><span class="n">H</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">cs</span><span class="p">,</span> <span class="n">sn</span><span class="p">):</span>
    <span class="n">x1</span> <span class="o">=</span> <span class="n">H</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">y1</span> <span class="o">=</span> <span class="n">H</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
    <span class="n">x2</span> <span class="o">=</span> <span class="n">cs</span> <span class="o">*</span> <span class="n">x1</span> <span class="o">-</span> <span class="n">sn</span> <span class="o">*</span> <span class="n">y1</span>
    <span class="n">y2</span> <span class="o">=</span> <span class="n">sn</span> <span class="o">*</span> <span class="n">x1</span> <span class="o">+</span> <span class="n">cs</span> <span class="o">*</span> <span class="n">y1</span>
    <span class="n">H</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">x2</span>
    <span class="n">H</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">y2</span>
    <span class="k">return</span> <span class="n">H</span>


<span class="k">class</span> <span class="nc">BatchedGmres</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Cell</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Implements a single restart of GMRES. The ``restart``-dimensional Krylov subspace</span>
<span class="sd">    This implementation solves a dense linear problem instead of building</span>
<span class="sd">    a QR factorization during the Arnoldi process.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">BatchedGmres</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">A</span> <span class="o">=</span> <span class="n">A</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">M</span> <span class="o">=</span> <span class="n">M</span>

    <span class="k">def</span> <span class="nf">construct</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tol</span><span class="o">=</span><span class="mf">1e-5</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">restart</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">maxiter</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="n">A</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">A</span><span class="p">)</span>
        <span class="n">M</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">M</span><span class="p">)</span>
        <span class="n">dtype</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">dtype</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">b_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
        <span class="n">atol</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">tol</span> <span class="o">*</span> <span class="n">b_norm</span><span class="p">,</span> <span class="n">_to_tensor</span><span class="p">(</span><span class="n">atol</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
        <span class="n">residual</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">b</span> <span class="o">-</span> <span class="n">A</span><span class="p">(</span><span class="n">x0</span><span class="p">))</span>
        <span class="n">unit_residual</span><span class="p">,</span> <span class="n">residual_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">residual</span><span class="p">)</span>
        <span class="n">k</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">x0</span>
        <span class="k">while</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="n">maxiter</span> <span class="ow">and</span> <span class="n">residual_norm</span> <span class="o">&gt;</span> <span class="n">atol</span><span class="p">:</span>
            <span class="n">pad_width</span> <span class="o">=</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),)</span> <span class="o">*</span> <span class="n">unit_residual</span><span class="o">.</span><span class="n">ndim</span> <span class="o">+</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">restart</span><span class="p">),)</span>
            <span class="n">V</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">pad</span><span class="p">(</span><span class="n">unit_residual</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="kc">None</span><span class="p">],</span> <span class="n">pad_width</span><span class="o">=</span><span class="n">pad_width</span><span class="p">)</span>
            <span class="n">H</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="n">restart</span><span class="p">,</span> <span class="n">restart</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
            <span class="n">k_iter</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
            <span class="n">breakdown</span> <span class="o">=</span> <span class="n">_to_tensor</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
            <span class="k">while</span> <span class="n">k_iter</span> <span class="o">&lt;</span> <span class="n">restart</span> <span class="ow">and</span> <span class="n">mnp</span><span class="o">.</span><span class="n">logical_not</span><span class="p">(</span><span class="n">breakdown</span><span class="p">):</span>
                <span class="n">V</span><span class="p">,</span> <span class="n">H</span><span class="p">,</span> <span class="n">breakdown</span> <span class="o">=</span> <span class="n">arnoldi_iteration</span><span class="p">(</span><span class="n">k_iter</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">H</span><span class="p">)</span>
                <span class="n">k_iter</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="n">beta_vec</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">restart</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
            <span class="n">beta_vec</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">residual_norm</span>
            <span class="n">a2</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">H</span><span class="p">,</span> <span class="n">H</span><span class="o">.</span><span class="n">T</span><span class="p">)</span>
            <span class="n">b2</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">H</span><span class="p">,</span> <span class="n">beta_vec</span><span class="p">)</span>
            <span class="n">c</span><span class="p">,</span> <span class="n">lower</span> <span class="o">=</span> <span class="n">cho_factor</span><span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">lower</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
            <span class="n">factor</span> <span class="o">=</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">lower</span><span class="p">)</span>
            <span class="n">y</span> <span class="o">=</span> <span class="n">cho_solve</span><span class="p">(</span><span class="n">factor</span><span class="p">,</span> <span class="n">b2</span><span class="p">)</span>
            <span class="n">dx</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">V</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">y</span><span class="p">)</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">dx</span>
            <span class="n">residual</span> <span class="o">=</span> <span class="n">b</span> <span class="o">-</span> <span class="n">A</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
            <span class="n">unit_residual</span><span class="p">,</span> <span class="n">residual_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">residual</span><span class="p">)</span>
            <span class="n">k</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="k">return</span> <span class="n">x</span>


<span class="k">class</span> <span class="nc">IterativeGmres</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Cell</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Implements a iterative GMRES. While building the ``restart``-dimensional</span>
<span class="sd">    Krylov subspace iteratively using Givens Rotation method, the algorithm</span>
<span class="sd">    constructs a Triangular matrix R which could be more easily solved.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">IterativeGmres</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">A</span> <span class="o">=</span> <span class="n">A</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">M</span> <span class="o">=</span> <span class="n">M</span>

    <span class="k">def</span> <span class="nf">construct</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">tol</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">restart</span><span class="p">,</span> <span class="n">maxiter</span><span class="p">):</span>
        <span class="n">A</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">A</span><span class="p">)</span>
        <span class="n">M</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">M</span><span class="p">)</span>

        <span class="n">_</span><span class="p">,</span> <span class="n">b_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
        <span class="n">atol</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">tol</span> <span class="o">*</span> <span class="n">b_norm</span><span class="p">,</span> <span class="n">atol</span><span class="p">)</span>

        <span class="n">Mb</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">Mb_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">Mb</span><span class="p">)</span>
        <span class="n">ptol</span> <span class="o">=</span> <span class="n">Mb_norm</span> <span class="o">*</span> <span class="n">mnp</span><span class="o">.</span><span class="n">minimum</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">atol</span> <span class="o">/</span> <span class="n">b_norm</span><span class="p">)</span>

        <span class="n">r</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">b</span> <span class="o">-</span> <span class="n">A</span><span class="p">(</span><span class="n">x0</span><span class="p">))</span>
        <span class="n">r</span><span class="p">,</span> <span class="n">r_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>

        <span class="n">iters</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
        <span class="k">while</span> <span class="n">iters</span> <span class="o">&lt;</span> <span class="n">maxiter</span> <span class="ow">and</span> <span class="n">r_norm</span> <span class="o">&gt;</span> <span class="n">atol</span><span class="p">:</span>
            <span class="n">V</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">pad</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="kc">None</span><span class="p">],</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),)</span> <span class="o">*</span> <span class="n">r</span><span class="o">.</span><span class="n">ndim</span> <span class="o">+</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">restart</span><span class="p">),))</span>
            <span class="n">dtype</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">result_type</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
            <span class="c1"># use eye() to avoid constructing a singular matrix in case of early</span>
            <span class="c1"># termination</span>
            <span class="n">R</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="n">restart</span><span class="p">,</span> <span class="n">restart</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
            <span class="n">givens</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">restart</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
            <span class="n">beta_vec</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">restart</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">dtype</span><span class="p">)</span>
            <span class="n">beta_vec</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">r_norm</span>

            <span class="n">k</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
            <span class="n">err</span> <span class="o">=</span> <span class="n">r_norm</span>
            <span class="k">while</span> <span class="n">mnp</span><span class="o">.</span><span class="n">logical_and</span><span class="p">(</span><span class="n">mnp</span><span class="o">.</span><span class="n">less</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">restart</span><span class="p">),</span> <span class="n">mnp</span><span class="o">.</span><span class="n">less</span><span class="p">(</span><span class="n">ptol</span><span class="p">,</span> <span class="n">err</span><span class="p">)):</span>
                <span class="n">V</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">arnoldi_iteration</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span>
                <span class="c1"># givens rotation</span>
                <span class="n">row_k</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="p">:]</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
                <span class="n">i</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
                <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">k</span><span class="p">:</span>
                    <span class="n">row_k</span> <span class="o">=</span> <span class="n">rotate_vectors</span><span class="p">(</span><span class="n">row_k</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">givens</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">givens</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
                    <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>

                <span class="k">if</span> <span class="n">row_k</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
                    <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">increase</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">absolute</span><span class="p">(</span><span class="n">row_k</span><span class="p">[</span><span class="n">k</span><span class="p">])</span> <span class="o">&lt;</span> <span class="n">mnp</span><span class="o">.</span><span class="n">absolute</span><span class="p">(</span><span class="n">row_k</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
                    <span class="n">t</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">increase</span><span class="p">,</span> <span class="o">-</span><span class="n">row_k</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">/</span> <span class="n">row_k</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">],</span> <span class="o">-</span><span class="n">row_k</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">/</span> <span class="n">row_k</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                    <span class="n">r</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="n">F</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">mnp</span><span class="o">.</span><span class="n">absolute</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span>
                    <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">increase</span><span class="p">,</span> <span class="n">r</span> <span class="o">*</span> <span class="n">t</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
                    <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">increase</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">r</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span>

                <span class="n">R</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">rotate_vectors</span><span class="p">(</span><span class="n">row_k</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
                <span class="n">beta_vec</span> <span class="o">=</span> <span class="n">rotate_vectors</span><span class="p">(</span><span class="n">beta_vec</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">givens</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
                <span class="n">err</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">absolute</span><span class="p">(</span><span class="n">beta_vec</span><span class="p">[</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
                <span class="n">k</span> <span class="o">+=</span> <span class="mi">1</span>

            <span class="n">y</span> <span class="o">=</span> <span class="n">solve_triangular</span><span class="p">(</span><span class="n">R</span><span class="p">[:,</span> <span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">beta_vec</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">trans</span><span class="o">=</span><span class="s1">&#39;T&#39;</span><span class="p">,</span> <span class="n">lower</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="n">dx</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">V</span><span class="p">[:,</span> <span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">y</span><span class="p">)</span>

            <span class="n">x</span> <span class="o">=</span> <span class="n">x0</span> <span class="o">+</span> <span class="n">dx</span>
            <span class="n">r</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">b</span> <span class="o">-</span> <span class="n">A</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
            <span class="n">r</span><span class="p">,</span> <span class="n">r_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
            <span class="n">x0</span> <span class="o">=</span> <span class="n">x</span>
            <span class="n">iters</span> <span class="o">+=</span> <span class="mi">1</span>

        <span class="k">return</span> <span class="n">x0</span>


<div class="viewcode-block" id="gmres"><a class="viewcode-back" href="../../../../api_python/scipy/mindspore.scipy.sparse.linalg.gmres.html#mindspore.scipy.sparse.linalg.gmres">[docs]</a><span class="k">def</span> <span class="nf">gmres</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">tol</span><span class="o">=</span><span class="mf">1e-5</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">restart</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">maxiter</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
          <span class="n">M</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">solve_method</span><span class="o">=</span><span class="s1">&#39;batched&#39;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    GMRES solves the linear system :math:`A x = b` for x, given A and b.</span>

<span class="sd">    A is specified as a function performing A(vi) -&gt; vf = A @ vi, and in principle</span>
<span class="sd">    need not have any particular special properties, such as symmetry. However,</span>
<span class="sd">    convergence is often slow for nearly symmetric operators.</span>

<span class="sd">    Note:</span>
<span class="sd">        In the future, MindSpore will report the number of iterations when convergence</span>
<span class="sd">        is not achieved, like SciPy. Currently it is None, as a Placeholder.</span>

<span class="sd">    Args:</span>
<span class="sd">        A (Union[Tensor, function]): 2D Tensor or function that calculates the linear</span>
<span class="sd">            map (matrix-vector product) :math:`Ax` when called like :math:`A(x)`.</span>
<span class="sd">            As function, `A` must return Tensor with the same structure and shape as its input matrix.</span>
<span class="sd">        b (Tensor): Right hand side of the linear system representing a single vector.</span>
<span class="sd">            Can be stored as a Tensor.</span>
<span class="sd">        x0 (Tensor, optional): Starting guess for the solution. Must have the same structure</span>
<span class="sd">            as `b`. If this is unspecified, zeroes are used. Default: None.</span>
<span class="sd">        tol (float, optional): Tolerances for convergence,</span>
<span class="sd">            :math:`norm(residual) &lt;= max(tol*norm(b), atol)`. We do not implement SciPy&#39;s</span>
<span class="sd">            &quot;legacy&quot; behavior, so MindSpore&#39;s tolerance will differ from SciPy unless you</span>
<span class="sd">            explicitly pass `atol` to SciPy&#39;s `gmres`. Default: 1e-5.</span>
<span class="sd">        atol (float, optional): The same as `tol`. Default: 0.0.</span>
<span class="sd">        restart (integer, optional): Size of the Krylov subspace (&quot;number of iterations&quot;)</span>
<span class="sd">            built between restarts. GMRES works by approximating the true solution x as its</span>
<span class="sd">            projection into a Krylov space of this dimension - this parameter</span>
<span class="sd">            therefore bounds the maximum accuracy achievable from any guess</span>
<span class="sd">            solution. Larger values increase both number of iterations and iteration</span>
<span class="sd">            cost, but may be necessary for convergence. The algorithm terminates</span>
<span class="sd">            early if convergence is achieved before the full subspace is built.</span>
<span class="sd">            Default: 20.</span>
<span class="sd">        maxiter (int): Maximum number of times to rebuild the size-`restart`</span>
<span class="sd">            Krylov space starting from the solution found at the last iteration. If GMRES</span>
<span class="sd">            halts or is very slow, decreasing this parameter may help.</span>
<span class="sd">            Default: None.</span>
<span class="sd">        M (Union[Tensor, function]): Preconditioner for A.  The preconditioner should approximate the</span>
<span class="sd">            inverse of A.  Effective preconditioning dramatically improves the</span>
<span class="sd">            rate of convergence, which implies that fewer iterations are needed</span>
<span class="sd">            to reach a given error tolerance. Default: None.</span>
<span class="sd">        solve_method (str): There are two kinds of solve methods,&#39;incremental&#39; or &#39;batched&#39;. Default: &quot;batched&quot;.</span>

<span class="sd">            - incremental: builds a QR decomposition for the Krylov subspace incrementally during</span>
<span class="sd">              the GMRES process using Givens rotations. This improves numerical stability and gives</span>
<span class="sd">              a free estimate of the residual norm that allows for early termination within a single &quot;restart&quot;.</span>
<span class="sd">            - batched: solve the least squares problem from scratch at the end of each GMRES</span>
<span class="sd">              iteration. It does not allow for early termination, but has much less overhead on GPUs.</span>

<span class="sd">    Returns:</span>
<span class="sd">        - Tensor, the converged solution. Has the same structure as `b`.</span>
<span class="sd">        - None, placeholder for convergence information.</span>

<span class="sd">    Supported Platforms:</span>
<span class="sd">        ``CPU`` ``GPU``</span>

<span class="sd">    Examples:</span>
<span class="sd">        &gt;&gt;&gt; import numpy as onp</span>
<span class="sd">        &gt;&gt;&gt; import mindspore.numpy as mnp</span>
<span class="sd">        &gt;&gt;&gt; from mindspore.common import Tensor</span>
<span class="sd">        &gt;&gt;&gt; from mindspore.scipy.sparse.linalg import gmres</span>
<span class="sd">        &gt;&gt;&gt; A = Tensor(mnp.array([[3, 2, 0], [1, -1, 0], [0, 5, 1]], dtype=mnp.float32))</span>
<span class="sd">        &gt;&gt;&gt; b = Tensor(mnp.array([2, 4, -1], dtype=mnp.float32))</span>
<span class="sd">        &gt;&gt;&gt; x, exitCode = gmres(A, b)</span>
<span class="sd">        &gt;&gt;&gt; exitCode            # 0 indicates successful convergence</span>
<span class="sd">        0</span>
<span class="sd">        &gt;&gt;&gt; onp.allclose(mnp.dot(A,x).asnumpy(), b.asnumpy())</span>
<span class="sd">        True</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">if</span> <span class="n">x0</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">x0</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
    <span class="n">size</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">size</span>
    <span class="k">if</span> <span class="n">maxiter</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">maxiter</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">size</span>  <span class="c1"># copied from scipy</span>
    <span class="k">if</span> <span class="n">restart</span> <span class="o">&gt;</span> <span class="n">size</span><span class="p">:</span>
        <span class="n">restart</span> <span class="o">=</span> <span class="n">size</span>

    <span class="k">if</span> <span class="n">M</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">M</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span>

    <span class="k">if</span> <span class="n">solve_method</span> <span class="o">==</span> <span class="s1">&#39;incremental&#39;</span><span class="p">:</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">IterativeGmres</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">)(</span><span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">tol</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">restart</span><span class="p">,</span> <span class="n">maxiter</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">solve_method</span> <span class="o">==</span> <span class="s1">&#39;batched&#39;</span><span class="p">:</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">BatchedGmres</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">)(</span><span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">tol</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">restart</span><span class="p">,</span> <span class="n">maxiter</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">_raise_value_error</span><span class="p">(</span><span class="s2">&quot;solve_method should be in (&#39;incremental&#39; or &#39;batched&#39;), but got </span><span class="si">{}</span><span class="s2">.&quot;</span>
                           <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">solve_method</span><span class="p">))</span>
    <span class="n">_</span><span class="p">,</span> <span class="n">x_norm</span> <span class="o">=</span> <span class="n">_safe_normalize</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
    <span class="n">info</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">mnp</span><span class="o">.</span><span class="n">isnan</span><span class="p">(</span><span class="n">x_norm</span><span class="p">),</span> <span class="n">_INT_NEG_ONE</span><span class="p">,</span> <span class="n">_INT_ZERO</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">x</span><span class="p">,</span> <span class="n">info</span></div>


<span class="k">class</span> <span class="nc">CG</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Cell</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Figure 2.5 from Barrett R, et al. &#39;Templates for the sulution of linear systems:</span>
<span class="sd">    building blocks for iterative methods&#39;, 1994, pg. 12-14</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">CG</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">A</span> <span class="o">=</span> <span class="n">A</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">M</span> <span class="o">=</span> <span class="n">M</span>

    <span class="k">def</span> <span class="nf">construct</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">tol</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">maxiter</span><span class="p">):</span>
        <span class="n">A</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">A</span><span class="p">)</span>
        <span class="n">M</span> <span class="o">=</span> <span class="n">_normalize_matvec</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">M</span><span class="p">)</span>

        <span class="k">def</span> <span class="nf">_my_norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">ord_</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">ord_</span> <span class="o">==</span> <span class="n">mnp</span><span class="o">.</span><span class="n">inf</span><span class="p">:</span>
                <span class="n">res</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">mnp</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">res</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">mnp</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span> <span class="o">**</span> <span class="mi">2</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">res</span>

        <span class="n">atol_</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">atol</span><span class="p">,</span> <span class="n">tol</span> <span class="o">*</span> <span class="n">_my_norm</span><span class="p">(</span><span class="n">b</span><span class="p">))</span>

        <span class="n">r</span> <span class="o">=</span> <span class="n">b</span> <span class="o">-</span> <span class="n">A</span><span class="p">(</span><span class="n">x0</span><span class="p">)</span>
        <span class="n">z</span> <span class="o">=</span> <span class="n">p</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
        <span class="n">rho</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
        <span class="n">k</span> <span class="o">=</span> <span class="n">_INT_ZERO</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">x0</span>
        <span class="k">while</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="n">maxiter</span> <span class="ow">and</span> <span class="n">_my_norm</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">atol_</span><span class="p">:</span>
            <span class="n">q</span> <span class="o">=</span> <span class="n">A</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
            <span class="n">alpha</span> <span class="o">=</span> <span class="n">rho</span> <span class="o">/</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">alpha</span> <span class="o">*</span> <span class="n">p</span>
            <span class="n">r</span> <span class="o">=</span> <span class="n">r</span> <span class="o">-</span> <span class="n">alpha</span> <span class="o">*</span> <span class="n">q</span>

            <span class="n">z</span> <span class="o">=</span> <span class="n">M</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
            <span class="n">rho_</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
            <span class="n">beta</span> <span class="o">=</span> <span class="n">rho_</span> <span class="o">/</span> <span class="n">rho</span>
            <span class="n">p</span> <span class="o">=</span> <span class="n">z</span> <span class="o">+</span> <span class="n">beta</span> <span class="o">*</span> <span class="n">p</span>
            <span class="n">rho</span> <span class="o">=</span> <span class="n">rho_</span>

            <span class="n">k</span> <span class="o">+=</span> <span class="mi">1</span>

        <span class="k">return</span> <span class="n">x</span>


<div class="viewcode-block" id="cg"><a class="viewcode-back" href="../../../../api_python/scipy/mindspore.scipy.sparse.linalg.cg.html#mindspore.scipy.sparse.linalg.cg">[docs]</a><span class="k">def</span> <span class="nf">cg</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">tol</span><span class="o">=</span><span class="mf">1e-5</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">maxiter</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">M</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Use Conjugate Gradient iteration to solve :math:`Ax = b`.</span>

<span class="sd">    The numerics of MindSpore&#39;s `cg` should exact match SciPy&#39;s `cg` (up to</span>
<span class="sd">    numerical precision).</span>

<span class="sd">    Derivatives of `cg` are implemented via implicit differentiation with</span>
<span class="sd">    another `cg` solve, rather than by differentiating *through* the solver.</span>
<span class="sd">    They will be accurate only if both solves converge.</span>

<span class="sd">    Note:</span>
<span class="sd">        In the future, MindSpore will report the number of iterations when convergence</span>
<span class="sd">        is not achieved, like SciPy. Currently it is None, as a Placeholder.</span>
<span class="sd">        Input `A` must represent a hermitian, positive definite matrix. If not,</span>
<span class="sd">        the output is wrong and inconsistent with scipy.</span>

<span class="sd">    Args:</span>
<span class="sd">        A (Union[Tensor, function]): 2D Tensor or function that calculates the linear</span>
<span class="sd">            map (matrix-vector product) :math:`Ax` when called like :math:`A(x)`.</span>
<span class="sd">            As function, `A` must return Tensor with the same structure and shape as its input matrix.</span>
<span class="sd">        b (Tensor): Right hand side of the linear system representing a single vector. Can be</span>
<span class="sd">            stored as a Tensor.</span>
<span class="sd">        x0 (Tensor): Starting guess for the solution. Must have the same structure as `b`. Default: None.</span>
<span class="sd">        tol (float, optional): Tolerances for convergence, :math:`norm(residual) &lt;= max(tol*norm(b), atol)`.</span>
<span class="sd">            We do not implement SciPy&#39;s &quot;legacy&quot; behavior, so MindSpore&#39;s tolerance will</span>
<span class="sd">            differ from SciPy unless you explicitly pass `atol` to SciPy&#39;s `cg`. Default: 1e-5.</span>
<span class="sd">        atol (float, optional): The same as `tol`. Default: 0.0.</span>
<span class="sd">        maxiter (int): Maximum number of iterations.  Iteration will stop after maxiter</span>
<span class="sd">            steps even if the specified tolerance has not been achieved. Default: None.</span>
<span class="sd">        M (Union[Tensor, function]): Preconditioner for A.  The preconditioner should approximate the</span>
<span class="sd">            inverse of A. Effective preconditioning dramatically improves the</span>
<span class="sd">            rate of convergence, which implies that fewer iterations are needed</span>
<span class="sd">            to reach a given error tolerance. Default: None.</span>

<span class="sd">    Returns:</span>
<span class="sd">        - Tensor, the converged solution. Has the same structure as `b`.</span>
<span class="sd">        - None, placeholder for convergence information.</span>

<span class="sd">    Raises:</span>
<span class="sd">        ValueError: If `x0` and `b` don&#39;t have the same structure.</span>
<span class="sd">        TypeError: If `A`, `x0` and `b` don&#39;t have the same float types(`mstype.float32` or `mstype.float64`).</span>

<span class="sd">    Supported Platforms:</span>
<span class="sd">        ``CPU`` ``GPU``</span>

<span class="sd">    Examples:</span>
<span class="sd">        &gt;&gt;&gt; import numpy as onp</span>
<span class="sd">        &gt;&gt;&gt; from mindspore.common import Tensor</span>
<span class="sd">        &gt;&gt;&gt; from mindspore.scipy.sparse.linalg import cg</span>
<span class="sd">        &gt;&gt;&gt; A = Tensor(onp.array([[1, 2], [2, 1]], dtype=&#39;float32&#39;))</span>
<span class="sd">        &gt;&gt;&gt; b = Tensor(onp.array([1, -1], dtype=&#39;float32&#39;))</span>
<span class="sd">        &gt;&gt;&gt; result, _ = cg(A, b)</span>
<span class="sd">        &gt;&gt;&gt; result</span>
<span class="sd">        Tensor(shape=[2], dtype=Float32, value= [-1.00000000e+00,  1.00000000e+00])</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">x0</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">x0</span> <span class="o">=</span> <span class="n">mnp</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">maxiter</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">maxiter</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

    <span class="k">if</span> <span class="n">M</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">M</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span>

    <span class="k">if</span> <span class="n">x0</span><span class="o">.</span><span class="n">shape</span> <span class="o">!=</span> <span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="p">:</span>
        <span class="n">_raise_value_error</span><span class="p">(</span>
            <span class="s1">&#39;Input x0 and b must have matching shapes: </span><span class="si">{}</span><span class="s1"> vs </span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x0</span><span class="o">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="p">))</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">F</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">float_types</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">F</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="o">!=</span> <span class="n">F</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">x0</span><span class="p">))</span> <span class="ow">or</span> <span class="p">(</span><span class="n">F</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="o">!=</span> <span class="n">F</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">A</span><span class="p">)):</span>
        <span class="n">_raise_type_error</span><span class="p">(</span><span class="s1">&#39;Input A, x0 and b must have same float types&#39;</span><span class="p">)</span>

    <span class="n">x</span> <span class="o">=</span> <span class="n">CG</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">M</span><span class="p">)(</span><span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">tol</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">maxiter</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">x</span><span class="p">,</span> <span class="kc">None</span></div>
</pre></div>

           </div>
           
          </div>
          <footer>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2021, MindSpore.

    </p>
  </div>
    
    
    
    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    
    provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>